/*
 * @Date: 2023-12-26 13:21:25
 * @LastEditors: lyx
 * @LastEditTime: 2023-12-27 09:44:49
 * @FilePath: \taro-template3\src\lib\request\taro-request.ts
 * @Description: 小程序 request·封装
 */

import Taro, { navigateTo } from "@tarojs/taro";
import createPromise from "../create-promise";
import { store } from "@/store/index";

/**
 * 创建 Fetch 请求处理函数
 *
 * @param config 请求配置
 * @returns 返回一个异步函数，用于发起请求
 */
function createFetchHandler(config?: Record<string, unknown>) {
  return async function (options: any): Promise<any> {
    const promise = createPromise();
    // 获取请求数据
    const data = options.data ?? ((options.params as any) || {});
    // 获取用户认证信息
    const {
      user: { auth },
    } = store.getState();

    // 定义请求头对象
    let _headers;
    // 如果存在认证令牌，则设置请求头中的Authorization字段
    if (auth.token) {
      _headers = {
        Authorization: JSON.stringify({ token: auth.token }),
      };
    }

    // 定义请求URL
    let url;
    // 如果请求URL以http开头，则直接使用该URL
    if (options.url.startsWith("http")) {
      url = options?.url;
    } else {
      // 否则根据前缀和URL拼接请求URL
      url = options.prefix
        ? options.prefix + options.url
        : process.env.SERVER_HOST + options?.url || "";
    }
    // 发起网络请求
    Taro.request({
      ...options,
      url,
      method: (options.method as any) || "GET",
      data,
      headers: {
        ...options.headers,
        ..._headers,
      },
      timeout: 60000,
      ...config,
      success(res) {
        // 如果响应是字符串或者响应数据中的code为0，则解析响应数据并解决promise
        if (typeof res === "string" || res?.data?.code === "0") {
          promise.resolve(res?.data);
        } else if (res?.data?.code === "A0230") {
          // 如果响应数据中的code为8003，则显示提示并跳转到登录页面
          Taro.showToast({
            title: res?.data.msg || "登录状态失效，请重新登录",
            icon: "none",
            duration: 2000,
          });
          setTimeout(() => {
            navigateTo({
              url: "/sub_common/pages/auth/index",
            });
          }, 2000);
        } else {
          // 其他情况则拒绝promise并传入响应数据作为错误信息
          promise.reject(res?.data);
        }
      },
      fail(error) {
        // 网络请求失败则拒绝promise并传入错误信息作为错误信息
        promise.reject(error);
      },
    });
    // 返回等待promise解决的返回值，以实现异步调用同步返回结果的效果。
    return await promise;
  };
}

export const request = createFetchHandler();

export default createFetchHandler;
